home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_56 / emstool.pas < prev    next >
Pascal/Delphi Source File  |  1995-01-01  |  6KB  |  256 lines

  1. {$G+}
  2. unit EMStool;
  3.  
  4. interface
  5.  
  6. Type PHandle=^THandle;
  7.      THandle=record handleNo:word;
  8.                     next:PHandle;
  9.                   end;
  10.  
  11. var FrameSEG:array[0..3] of Word; { real mem segment for every page }
  12.     FramePTR:array[0..3] of pointer; { real mem pointer (ofs=0) for every page }
  13.     EMSinstalled:boolean;
  14.     EMSversion:real;
  15.     EmsEC:Integer;
  16.     HandleList:PHandle;
  17.  
  18. function EmsFreePages : integer;
  19. function EmsAlloc( Pages : integer ) : integer;
  20. function EmsFree(Handle : integer) : boolean;
  21. function EmsMap(Handle,LogPage:integer; PhysPage:byte) : boolean;
  22. function EmsSaveMap( Handle : integer ) : boolean;
  23. function EmsRestoreMap( Handle : integer ) : boolean;
  24. procedure PrintErr;
  25.  
  26. implementation
  27.  
  28. uses dos;
  29.  
  30. var oldexitproc:pointer;
  31.  
  32. function checkEMS:boolean;
  33. type EmmName  = array [1..8] of char;
  34.      EmmNaPtr = ^EmmName;
  35. const Name : EmmName = 'EMMXXXX0';
  36. var Regs  : Registers;
  37.  
  38. begin
  39.   Regs.ax := $35 shl 8 + $67;
  40.   msdos( Regs );
  41.   checkEms := (EmmNaPtr(Ptr(Regs.ES,10))^ = Name);
  42. end;
  43.  
  44. procedure getEmsVersion;
  45.                                                                         
  46. var Regs : Registers;      { Prozessorregister für den Interruptaufruf }
  47.                                                                         
  48. begin
  49.   Regs.ah := $46;
  50.   Intr($67, Regs);
  51.   if (Regs.ah <>0 ) then
  52.     begin
  53.       EmsEC := Regs.ah;
  54.       EmsVersion := 0.0;
  55.     end
  56.   else
  57.    EmsVersion := 0.1*(Regs.al and 15) + (Regs.al shr 4);
  58. end;
  59.  
  60. procedure insert_handle(handle:word);
  61. var n:PHandle;
  62.   begin
  63.     if Maxavail<sizeof(Thandle) then exit; { sorry - forget it }
  64.     new(n);
  65.     n^.next:=handlelist;
  66.     handlelist:=n;
  67.     n^.handleNo:=handle;
  68.   end;
  69.  
  70. PROCEDURE remove_handle(handle:word);
  71. var h,i:Phandle;
  72.   begin
  73.     h:=handlelist;i:=Nil;
  74.     while (h<>Nil) and (h^.handleNo<>handle) do begin i:=h;h:=h^.next end;
  75.     if h=Nil then exit;
  76.     if i=Nil then
  77.       begin
  78.         handlelist:=h^.next;
  79.         h^.next:=Nil;
  80.         dispose(h);
  81.       end
  82.     else
  83.       begin
  84.         i^.next:=h^.next;
  85.         h^.next:=Nil;
  86.         dispose(h);
  87.       end;
  88.   end;
  89.  
  90. procedure freeallpages;
  91. { ha that's why I created this tool -
  92.   if there's a division by zero or something
  93.   then free the pages allocated by this program ! - no problem :) }
  94.   begin
  95.     while handlelist<>Nil do
  96.       Emsfree(handlelist^.handleNo);
  97.   end;
  98.  
  99. procedure EmsExitRoutine; far;
  100.   begin
  101.     if handlelist<>Nil then freeallpages;
  102.     exitproc:=oldexitproc;
  103.   end;
  104.  
  105. function EmsFrameSeg : word; assembler;
  106. asm
  107.   mov       ah,041h
  108.   int       67h
  109.   cmp       ah,0
  110.   je        @@WasOk
  111.   mov       bx,0ffffh
  112.   shr       ax,8
  113.   mov       [EmsEC],ax
  114. @@WasOk:
  115.   mov       ax,bx
  116. end;
  117.  
  118. function EmsFreePages : integer; assembler;
  119. asm
  120.   mov         ah,42h
  121.   xor         al,al
  122.   int         67h
  123.   cmp         ah,0
  124.   je          @@wasOk
  125.   shr         ax,8
  126.   mov         [EmsEC],ax
  127.   mov         bx,0
  128. @@wasok:
  129.   mov         ax,bx
  130. end;
  131.  
  132. function EmsAlloc( Pages : integer ) : integer; assembler;
  133. asm
  134.    mov       ah,043h
  135.    mov       bx,[Pages]
  136.    int       67h
  137.    cmp       ah,0
  138.    je        @@wasOK
  139.    mov       dx,0ffffh
  140.    shr       ax,8
  141.    mov       [EmsEC],ax
  142. @@wasOk:
  143.    mov       ax,dx
  144.    cmp       ax,0ffffh
  145.    je        @@donotinsert
  146.    push      ax
  147.    push      ax
  148.    call      insert_handle
  149.    pop       ax
  150. @@donotinsert:
  151. end;
  152.  
  153. function EmsFree(Handle : integer) : boolean; assembler;
  154. asm
  155.   mov       ah,045h
  156.   mov       dx,[handle]
  157.   int       67h
  158.   shr       ax,8
  159.   mov       [EmsEC],ax
  160.   cmp       ax,0
  161.   je        @@failed
  162.   mov       dx,[handle]
  163.   push      dx
  164.   call      remove_handle
  165.   mov      ax,-1
  166. @@failed:
  167.   inc      ax
  168. end;
  169.  
  170. function EmsMap(Handle,LogPage:integer; PhysPage:byte) : boolean; assembler;
  171. asm
  172.   mov      ah,044h
  173.   mov      al,[physPage]
  174.   mov      bx,[LogPage]
  175.   mov      dx,[handle]
  176.   int      67h
  177.   shr      ax,8
  178.   mov      [EmsEC],ax
  179.   cmp      ax,0
  180.   je       @@failed
  181.   mov      ax,-1
  182. @@failed:
  183.   inc      ax
  184. end;
  185.  
  186. function EmsSaveMap( Handle : integer ) : boolean; assembler;
  187. asm
  188.   mov       ah,047h
  189.   mov       dx,[handle]
  190.   int       67h
  191.   shr       ax,8
  192.   mov       [EmsEC],ax
  193.   cmp      ax,0
  194.   je       @@failed
  195.   mov      ax,-1
  196. @@failed:
  197.   inc      ax
  198. end;
  199.  
  200. function EmsRestoreMap( Handle : integer ) : boolean; assembler;
  201. asm
  202.   mov       ah,048h
  203.   mov       dx,[handle]
  204.   int       67h
  205.   shr       ax,8
  206.   mov       [EmsEC],ax
  207.   cmp      ax,0
  208.   je       @@failed
  209.   mov      ax,-1
  210. @@failed:
  211.   inc      ax
  212. end;
  213.  
  214. procedure PrintErr;
  215. begin
  216.   writeln('ATTENTION! Error while accessing EMS memory !');
  217.   write('     ... ');
  218.   if ((EmsEC<$80) or (EmsEc>$8E) or (EmsEc=$82)) then
  219.     writeln('unknown error code :',EmsEC)
  220.   else
  221.     case EmsEC of
  222.       $80 : writeln('Internal EMS driver error');
  223.       $81 : writeln('EMS hardware failure');
  224.       $83 : writeln('Unknown EMS handle');
  225.       $84 : writeln('This EMS-function does not exist');
  226.       $85 : writeln('No more free EMS handles');
  227.       $86 : writeln('Error with save/restore mapping');
  228.       $87 : writeln('More pages requested than available');
  229.       $88 : writeln('No enough free pages');
  230.       $89 : writeln('0 pages requested ?');
  231.       $8A : writeln('Problem with access - this logical page does not belong to this handle');
  232.       $8B : writeln('Wrong page number');
  233.       $8C : writeln('Not enough memory for save mapping');
  234.       $8D : writeln('Mapping allready saved');
  235.       $8E : writeln('Error restore mapping - was not saved before');
  236.     end;
  237. end;
  238.  
  239. begin
  240.   EMSinstalled:=checkEMS;
  241.   if EMSinstalled then
  242.     begin
  243.       getEMSversion;
  244.       FrameSEG[0]:=EmsFrameSeg;
  245.       FrameSEG[1]:=FrameSEG[0] + 1024;
  246.       FrameSEG[2]:=FrameSEG[1] + 1024;
  247.       FrameSEG[3]:=FrameSEG[2] + 1024;
  248.       Frameptr[0]:=ptr(Frameseg[0],0);
  249.       Frameptr[1]:=ptr(Frameseg[1],0);
  250.       Frameptr[2]:=ptr(Frameseg[2],0);
  251.       Frameptr[3]:=ptr(Frameseg[3],0);
  252.     end;
  253.   HandleList:=Nil;
  254.   oldexitproc:=exitproc;
  255.   exitproc:=@EmsExitRoutine;
  256. end.